package com.ruoyi.crm.service.impl;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.crm.domain.AssignRecord;
import com.ruoyi.crm.domain.Business;
import com.ruoyi.crm.mapper.AssignRecordMapper;
import com.ruoyi.crm.service.IAssignRecordService;
import com.ruoyi.crm.service.IBusinessService;
import com.ruoyi.crm.service.RemindedService;
import lombok.extern.slf4j.Slf4j;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ruoyi.crm.mapper.ClueMapper;
import com.ruoyi.crm.domain.Clue;
import com.ruoyi.crm.service.IClueService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;

/**
 * 线索管理Service业务层处理
 * 
 * @author ruoyi
 * @date 2023-03-13
 */
@Service
@Slf4j
public class ClueServiceImpl implements IClueService 
{
    @Resource
    private AssignRecordMapper assignRecordMapper;
    @Resource
    private ClueMapper clueMapper;

    @Resource
    private KieContainer kieContainer;
    @Resource
    private IBusinessService businessService;
    @Resource
    private IAssignRecordService assignRecordService;

    @Resource
    private RemindedService remindedService;
    //从配置文件读取
    @Value("${crm.remind.ahead-of-time:60m}")
    private Duration aheadOfTime;
    /**
     * 查询线索管理
     * 
     * @param id 线索管理主键
     * @return 线索管理
     */
    @Override
    public Clue selectClueById(Long id)
    {
        return clueMapper.selectClueById(id);
    }

    /**
     * 查询线索管理列表
     * 
     * @param clue 线索管理
     * @return 线索管理
     */
    @Override
    public List<Clue> selectClueList(Clue clue)
    {
        return clueMapper.selectClueList(clue);
    }

    /**
     * 新增线索管理
     * 
     * @param clue 线索管理
     * @return 结果
     */
    @Override
    public int insertClue(Clue clue)
    {
        clue.setStatus(Clue.Status.NEW.getValue());
        clue.setCreateBy(SecurityUtils.getUsername());
        clue.setCreateTime(DateUtils.getNowDate());
        return clueMapper.insertClue(clue);
    }

    /**
     * 修改线索管理
     * 
     * @param clue 线索管理
     * @return 结果
     */
    @Override
    public int updateClue(Clue clue)
    {
//        Date nextTime=clue.getNextTime();
//        Date now=new Date();
//        if(StringUtils.hasText(clue.getPhone()) && nextTime.after(now)){
//            LocalDateTime localDateTime=LocalDateTime.from(nextTime.toInstant().atZone(ZoneId.systemDefault()));
//            LocalDateTime notifyTime=localDateTime.plusMinutes(-aheadOfTime.toMinutes());
//
//            String format=notifyTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
//            log.debug("定时任务在 {}执行，通知{}",format,clue.getPhone());
//            remindedService.createJob(notifyTime,"task:clue"+clue.getId(),clue.getPhone(),"定时提醒线索【"+clue.getId()+"】");
//    }
        clue.setUpdateBy(SecurityUtils.getUsername());
        clue.setUpdateTime(DateUtils.getNowDate());
        return clueMapper.updateClue(clue);
    }

    /**
     * 批量删除线索管理
     * 
     * @param ids 需要删除的线索管理主键
     * @return 结果
     */
    @Override
    public int deleteClueByIds(Long[] ids)
    {
        return clueMapper.deleteClueByIds(ids);
    }

    /**
     * 删除线索管理信息
     * 
     * @param id 线索管理主键
     * @return 结果
     */
    @Override
    public int deleteClueById(Long id)
    {
        return clueMapper.deleteClueById(id);
    }

    @Override
    @Transactional
    public int uploadClues(List<Clue> clues) {
        int sum=0;
        KieSession kieSession=kieContainer.newKieSession();
        for (Clue clue : clues) {
           //调用规则引擎，自动分配归属人
            kieSession.insert(clue);
            kieSession.fireAllRules();
            //转换新增数据中的字典表数据（中文转数字）
            clue.setStatus(Clue.Status.NEW.getValue());
            clue.setChannel(DictUtils.getDictValue("clues_item",clue.getChannel()));
            clue.setSex(DictUtils.getDictValue("sys_user_sex",clue.getSex()));
            clue.setLevel(DictUtils.getDictValue("clues_level",clue.getLevel()));
            clue.setSubject(DictUtils.getDictValue("course_subject",clue.getSubject()));
            sum+=this.insertClue(clue);

            //分配线索给指定用户
            AssignRecord assignRecord=new AssignRecord();
            assignRecord.setType(AssignRecord.Type.CLUE.name());
            assignRecord.setAssignId(clue.getId());
            assignRecord.setCreateTime(new Date());
            setUserInfo(assignRecord,clue.getOwner());
            assignRecordService.insertAssignRecord(assignRecord);
        }
        kieSession.destroy();
        return sum;
    }

    //伪线索上报
    // 1.falseCount最大值3（伪线索失效次数）
    //状态改为 伪线索
    //状态更新为0 非最新
    //归属人改为空
    @Override
    public int falseClue(Long id) {
        Clue clue=this.selectClueById(id);
        if(clue.getFalseCount()>=Clue.FALSE_COUNT_LIMIT){
            throw  new RuntimeException("伪线索次数超限");
        }
        assignRecordMapper.updateLates(id,"0",AssignRecord.Type.CLUE.getValue());

        clue.setFalseCount(clue.getFalseCount()+1);
        clue.setUpdateTime(new Date());
        clue.setStatus(Clue.Status.FALSE.getValue());
        return this.updateClue(clue);
    }

    @Override
    @Transactional
    public int transform(Long id) {
        Clue clue=this.selectClueById(id);
        clue.setStatus(Clue.Status.To_BUSINESS.getValue());
        this.updateClue(clue);

        Business business=new Business();
        BeanUtils.copyProperties(clue,business);
        business.setStatus(Clue.Status.NEW.getValue());
        return businessService.insertBusiness(business);
    }

    //捞取线索
    //1.状态修改未已分配
    //2插入一条分配记录
    @Override
    public int resetClue(Long id) {
      AssignRecord assignRecord=new AssignRecord();
      assignRecord.setType(AssignRecord.Type.CLUE.name());
      assignRecord.setAssignId(id);
      assignRecord.setUserId(SecurityUtils.getUserId());
      assignRecord.setUserName(SecurityUtils.getUsername());
        return assignRecordService.insertAssignRecord(assignRecord);
    }

    private void setUserInfo(AssignRecord assignRecord,String owner){
            Map<String, Object> userINfo = getUserINfo(owner);
            assignRecord.setUserId((Long)userINfo.get("user_id"));
            assignRecord.setDeptId((Long)userINfo.get("dept_Id"));
            assignRecord.setUserName(owner);

        }
    //新增多条数据时提高效率，手动缓存
    public Map<String,Object> getUserINfo(String userName){
        final  String key ="crm:clue:userInfo:"+userName;
        RedisCache redisCache= SpringUtils.getBean(RedisCache.class);
        Map<String,Object> cacheMap=redisCache.getCacheMap(key);
        if(cacheMap.isEmpty()){
            cacheMap=clueMapper.selectUserInfo(userName);
            redisCache.setCacheMap(key,cacheMap);
            redisCache.expire(key,5, TimeUnit.MINUTES);
        }
     return cacheMap;
    }
}
